﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Redbrick.Silverlight.Controls
{
    [TemplatePart(Name=MenuItem.MenuTextPart,Type=typeof(TextBlock))]

    [TemplateVisualState(Name = MenuItem.NormalMenuItemState, GroupName = MenuItem.VisualStateGroup)]
    [TemplateVisualState(Name = MenuItem.SelectedMenuItem, GroupName = MenuItem.VisualStateGroup)]
    [TemplateVisualState(Name = MenuItem.DisabledMenuItem, GroupName = MenuItem.VisualStateGroup)]

    public class MenuItem : Control
    {
        public const string MenuTextPart ="Part_MenuText";

        public const string VisualStateGroup = "CommonStates";
        public const string NormalMenuItemState = "Normal";
        public const string SelectedMenuItem = "Selected";
        public const string DisabledMenuItem = "Disabled";


        #region Consts & Settings


        #endregion Consts & Settings

        #region Declarations

        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(MenuItem), new PropertyMetadata(null, MenuItem.CommandPropertyUpdated));
        public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(MenuItem), new PropertyMetadata(null));
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MenuItem), new PropertyMetadata(string.Empty));
        public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool), typeof(MenuItem), new PropertyMetadata(false));


        private TextBlock _menuText = null;

        #endregion Declarations

        #region Constructor

        public MenuItem()
        {
            this.DefaultStyleKey = typeof(MenuItem);
        }

        #endregion Constructor

        #region Methods


        #endregion Methods

        #region Events

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this._menuText = this.GetTemplateChild(MenuItem.MenuTextPart) as TextBlock;
            if (this._menuText == null) throw new NotImplementedException("Template Part \"" + MenuItem.MenuTextPart + "\" is required, and should be a TextBlock");
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);
            if (this.Command != null && this.Command.CanExecute(this.DataContext))
                this.Command.Execute(this.DataContext);
        }
        private static void CommandPropertyUpdated(object sender, DependencyPropertyChangedEventArgs args)
        {
            ICommand newCommand = args.NewValue as ICommand;
            ICommand oldCommand = args.OldValue as ICommand;
            MenuItem menuItem = sender as MenuItem;
            if (newCommand != null) newCommand.CanExecuteChanged += new EventHandler(menuItem.Command_CanExecuteChanged);
            if (oldCommand != null) oldCommand.CanExecuteChanged -= menuItem.Command_CanExecuteChanged;
        }

        private void Command_CanExecuteChanged(object sender, EventArgs e)
        {
            this.IsEnabled = this.Command.CanExecute(this.DataContext);
        }

        #endregion Events

        #region Properties

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        public ImageSource Image
        {
            get { return (ImageSource)GetValue(ImageProperty); }
            set { SetValue(ImageProperty, value); }
        }
        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }
        public bool IsChecked
        {
            get { return (bool)GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty, value); }
        }
        //public new bool IsEnabled { get { return this.Command == null ? true : this.Command.CanExecute(this.DataContext); } }

        #endregion Properties
    }
}
